<template>
  <el-card shadow="always" :body-style="{ padding: '20px' }">
    <template v-slot:header>
      <el-button type="primary" size="default" icon="ele-Plus" @click="showAddDialog">添加</el-button>
    </template>

    <!-- ---------------------------------------------------------------- 
    element-plus当中表格和html当中的表格不一样
    以列为单位，el-table-column代表表格的列，表格有几列就复制几个
    table身上会有一些属性： 
      data属性专门用于往table当中传递动态数据，而且这个数据必须是对象的数组
      border 边框，如果有边框就加上，如果不要边框就不要
      stripe 代表斑马状  如果你需要就加 不需要就不加
    column身上也会有一些属性
      type 代表这个列的类型  type的值为index，代表序号列
      align 代表列当中内容对其方式  align：center
      width 代表列的宽度  注意宽度在写的时候没有px 直接写数字，就代表了多少px
            如果不设置width，那么所有的列平分天下
      prop  代表后续这一列在显示动态数据的时候，显示的是对象的哪个属性
      label 代表列名
    ------------------------------------------------------------------ -->
    <el-table :data="trademarkList" border stripe>
      <el-table-column type="index" align="center" width="80" label="序号"></el-table-column>
      <el-table-column label="品牌名称" prop="tmName"></el-table-column>
      <el-table-column label="品牌LOGO">
        <!-- 这里是作用域插槽的使用 -->
        <!-- v-slot= 代表接收作用域插槽回传给父组件的数据 row:行 -->
        <template v-slot="{ row, $index }">
          <img :src="row.logoUrl" style="width:100px ;height: 60px;">
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <!-- 使用作用域插槽，目的是为了知道后期修改删除的是哪个row -->
        <template v-slot="{ row, $index }">
          <el-button type="warning" size="small" icon="ele-Edit" @click="showUpdateDialog(row)">修改</el-button>
          <el-button type="danger" size="small" icon="ele-Delete" @click="deleteTrademark(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!--  @size-change="handleSizeChange"
      @current-change="handleCurrentChange" -->
    <!-- 
        1、当前页
        2、每页数量
        3、总条数
        4、连续数
        配个事件  切换页码的事件
       -->
    <!-- 分页器 -->
    <el-pagination 
    @size-change="handleSizeChange" 
    @current-change="getTrademarkList" 
    style="margin-top:20px"
    v-model:current-page="page" 
    v-model:page-size="limit" 
    :total="total" 
    :pager-count="9" 
    :page-sizes="[3, 5, 7, 10]"
    layout=" prev, pager, next, jumper,->,sizes,total" />

    <!-- dialog对话框 -->
    <el-dialog v-model="dialogFormVisible" :title="`${tmForm.id ? '修改品牌' : '添加品牌'}`">
        <!-- :model="tmForm" 主要是用来做表单验证用的，只要是做表单验证 -->
        <el-form 
        style="80%" 
        :rules="rules" 
        :model="tmForm"
        >
          <el-form-item label="品牌名称" label-width="100px" prop="tmName">
            <el-input autocomplete="off"/>
          </el-form-item>
          <!-- 上传组件 -->
          <el-form-item label="品牌LOGO" label-width="100px" prop="logoUrl">
            <el-upload
              class="avatar-uploader"
              action="/app-dev/admin/product/fileUpload"
              :show-file-list="false"
              :on-success="handleAvatarSuccess"
              :before-upload="beforeAvatarUpload"
            >
              <img v-if="tmForm.logoUrl" :src="tmForm.logoUrl" class="avatar" />
              <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
              <template #tip>
                <div class="el-upload__tip">
                  上传的图片必须是jpg且不能大于2M
                </div>
            </template>
            </el-upload>
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="dialogFormVisible = false">取消</el-button>
            <el-button type="primary" @click="addOrUpdateTrademark">
              确定
            </el-button>
          </span>
        </template>
      </el-dialog>

  </el-card>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
  name: 'Trademark'
})
</script>
<script lang="ts" setup>
import { ref, onMounted,nextTick } from 'vue'
import trademarkApi, { type TrademarkData } from '@/api/trademark'
import { ElMessage, ElMessageBox, type FormRules } from 'element-plus';
import { Plus } from '@element-plus/icons-vue'
import type { UploadProps } from 'element-plus'


// 功能1：搭建静态列表需要的数据及获取初始化动态数据列表
const page = ref(1)
const limit = ref(3)
// ref是一个函数 这个函数在定义的时候，定义了泛型，这个泛型也是决定了ref函数返回值的类型
// 我们在使用调用ref函数的时候就可以确定它定义时候的泛型，你确定的类型就是返回值的类型
const trademarkList = ref<TrademarkData[]>([])
const total = ref(0)
// 请求获取品牌列表
// 请求获取品牌列表
// 这个函数又在做函数又在做回调函数
// 第一次在mounted当中是做为函数调用
// 使用再切换页码的事件后面是作为回调使用
const getTrademarkList = async (num: number = 1) => {
  page.value = num
  try {
    const result = await trademarkApi.getPageList(page.value, limit.value)
    // console.log(result);
    // 获取品牌列表数据保存起来
    trademarkList.value = result.records
    // 获取总条数数据保存起来
    total.value = result.total
  } catch (error) {
    ElMessage.error('获取品牌列表失败')
  }
}
onMounted(() => {
  getTrademarkList()
})
// // 处理切换页码
// const handleCurrentChange= (num:number) => {
//   // console.log(num); // 1 2 3 4 5 6 ....
//   // 修改当前点击页面
//   page.value = num 
//   // 刷新页面
//   getTrademarkList()
// }

// 处理切换每页的数量
// 这个函数不能和上面哪个一样，直接合并到请求的函数当中，因为参数是有顺序的
const handleSizeChange = (size: number) => {
  // console.log(limit);// 3 5 7 10
  // 修改每页展示数量
  limit.value = size
  // 刷新页面
  getTrademarkList()
}





// 功能2、添加的dialog需要的数据及添加收集数据的逻辑
const dialogFormVisible = ref(false)
// 上传组件使用的动态数据和函数 
// const imageUrl = ref('')
const handleAvatarSuccess: UploadProps['onSuccess'] = (
  response,
  uploadFile
) => {
  // console.log(response,uploadFile);

  //拿到的是本地路径，没用
  // imageUrl.value = URL.createObjectURL(uploadFile.raw!)  
  // console.log(imageUrl.value);

  //这个才是收集我们上传成功的网络路径
  tmForm.value.logoUrl = response.data
}
// 对上传的文件进行格式和大小的限制
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (rawFile.type !== 'image/jpeg') {
    ElMessage.error('图片必须是jpg格式!')
    return false
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('图片的大小不能超过2MB!')
    return false
  }
  return true
}
// 点击添加按钮显示对话框
const showAddDialog = ()=>{
  dialogFormVisible.value = true

  // 清空dialog当中的内容,解决添加完取消，再次点击添加数据依然存在的问题
  tmForm.value = {
    tmName:'',
    logoUrl:''
  }

    // 等待dom更新完成后，执行操作
    nextTick(() => {
    // 清除表单验证的结果
    tmFormRef.value.resetFields()
    // 清空dialog当中的内容 解决点击修改又取消，再次点击添加数据依然存在的问题
    tmForm.value = {
      tmName:'',
      logoUrl:''
    }
  })
}
/* 添加品牌需要收集一个品牌对象，那么我们要考虑这些事****************************************
  1、收集什么
      收集的东西要看接口文档当中参数需要什么东西，需要什么我们就朝这个目标去收集
      {
        tmName,
        logoUrl
      }
  2、收集到哪
        需要自己定义一个对象去收集
  3、怎么收集
        看你写的结构来决定  如果是表单元素，我们一般用的v-model，如果不是，那么我们可能要写逻辑去收集 
**************************************************************************************** */
// 定义收集的品牌对象
const tmForm = ref<TrademarkData>({
  tmName:'',
  logoUrl:''
})




// 功能3、修改的收集数据逻辑
const showUpdateDialog = (row:TrademarkData) => {
  // 显示对话框
  dialogFormVisible.value = true
  // 数据回显
  // tmForm.value = row
  /* 
  拷贝  --> 数据拷贝
  拷贝的特点： 堆当中必须出现新的空间地址才叫拷贝
  下面两个都不会拷贝
  var a = 10
  var b = a

  var obj = {m:100}
  var obj1 = obj */
  //解决修改tmForm的时候，row的数据也在跟着改变的bug
  tmForm.value = {...row}
}




// 功能4、添加和修改的确认发请求逻辑
// 点击确定按钮去发请求添加品牌或者修改品牌
const addOrUpdateTrademark = async () => {
  // 1、获取收集好的参数数据 tmForm
  let trademark = tmForm.value
	// 2、整理收集好的参数数据
	// 3、发送请求
  try {
    await trademarkApi.addOrUpdata(trademark)
    // 4、成功干啥
    // 成功的弹框提示 判断是否有id来确定是添加还是修改
    ElMessage.success(trademark.id ? '修改品牌成功' : '添加品牌成功')
    // 关闭对话框
    dialogFormVisible.value = false
    // 刷新页面 
    // 如果有id就是 修改：刷新页面到当前页
    // 如果无id就是 添加：刷新页面到当第一页
    getTrademarkList(trademark.id ? page.value : 1)
  } catch (error) {
    // 5、失败干啥
    // 失败的弹框提示 判断是否有id来确定是添加还是修改
    ElMessage.error(trademark.id ? '修改品牌失败' : '添加品牌失败')
  }
}



// 功能5、删除品牌的逻辑
// 点击删除按钮逻辑
const deleteTrademark = (row: TrademarkData) => {
  // MessageBox 消息弹框
  ElMessageBox.confirm(
    `你确定要删除${row.tmName}`,
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
  // messagebox返回的也是一个promise，这个promise是内部封装过的
  // .then代表的是成功的回调，在这代表的是点击确认的逻辑
  // .catch代表的是失败的回调，在这代表的是点击取消的逻辑
  .then( async () => {
    try {
      // 调用api 传递参数发送请求
      await trademarkApi.delete(row.id as number)
      // 成功弹窗
      ElMessage({
        type: 'success',
        message: '删除品牌成功',
        // 弹窗停留时间 不写默认就是3秒
        // duration: 1000
      })
      // 刷新页面
      // 如果删除的当前页数量是大于1，那么删除后还是停留在当前页
      // 如果当前页数量不大于1就是1，那么删除后是要停留在上一页
      getTrademarkList(trademarkList.value.length > 1 ? page.value : page.value - 1)
    } catch (error) {
      // 失败弹窗
      ElMessage({
        type: 'error',
        message: '删除品牌失败',
      })
    }
  })
  .catch(() => {
    // 取消弹窗
    ElMessage({
      type: 'info',
      message: '取消删除成功',
    })
  })
}




// 功能6、表单验证-单个校验
// 这个rules定义的就是我们要的验证规则
// 这些规则都是内置的规则
// 一个属性对应 个规则数组， 规则数组当中每 个规则都是一个对象
// 每个规则对象包含三种属性，1、 内置规则 2、 报错信息3、 触发方式
// 触发方式包含3种: 1、失去焦点 2、修改的时候 3、整体校验的时候
// 单个校验(在输入某个数据的时候只对这一 个进行校验)
// 整体校验(点击确定的时候对所有的进行校验)
const rules = ref<FormRules>({
  tmName: [
    { required: true, message: '品牌名称必须填写', trigger: 'blur' },
    { min: 2, max: 10, message: '品牌名称长度必须在2-10', trigger: 'change' },
  ],
  // 这个upload组件在做表单验证的时候，只有整体校验才能触发
  logoUrl: [
    {
      required: true,
      message: '品跑LOGO图片必须上传',
      trigger: 'change',
    },
  ],
})
// tmFormRef拿到表单的组件对象
const tmFormRef = ref()
</script>

<style scoped>
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>